Introduction
Xamarin.Uitest is a testing framework using which we can automate our application in C# using the Nunit framework which will run on Android and iOS.
Each Uitest is written as methods and is referred to as tests.
The test cases will interact with the UI and perform the operations just as a user does like tapping on buttons, entering text and performing gestures like swiping or pinching.
Setting up Xamarin UiTest
File-->New Solution-->Multiplatform-->Tests-->Solution name.

After creating the project the solution will look like this:

We will start with App Initializer and will try to understand how it works.
- public static IApp StartApp(Platform platform)
- {
- // TODO: If the iOS or Android app being tested is included in the solution
- // then open the Unit Tests window, right click Test Apps, select Add App Project
- // and select the app projects that should be tested.
- //
- // The iOS project should have the Xamarin.TestCloud.Agent NuGet package
- // installed. To start the Test Cloud Agent the following code should be
- // added to the FinishedLaunching method of the AppDelegate:
- //
- // #if ENABLE_TEST_CLOUD
- // Xamarin.Calabash.Start();
- // #endif
- if (platform == Platform.Android)
- {
- return ConfigureApp
- .Android
- // TODO: Update this path to point to your Android app and uncomment the
- // code if the app is not included in the solution.
- //.ApkFile ("../../../Droid/bin/Debug/xamarinforms.apk")
- .StartApp();
- }
- return ConfigureApp
- .iOS
- // TODO: Update this path to point to your iOS app and uncomment the
- // code if the app is not included in the solution.
- //.AppBundle ("../../../iOS/bin/iPhoneSimulator/Debug/XamarinForms.iOS.app")
- .StartApp();
- }
Start App will be the first function called when starting the Test Execution.
So here we have to do the Setup for iOS and Android.
Android Setup
We can either use the application that is already there on the Device using the Package name of the Application or we can install the apk from a specified location.
- //Already Installed on device
- return ConfigureApp
- .Android
- .Debug()
- .InstalledApp(“com.Abc.XYZ”)// Package name of Application .
- .DeviceSerial(“ce081718341fbf1f01")//Pass DeviceSerial, in case more than one device connected.
- .StartApp();
- //Specified Location
- return ConfigureApp
- .Android
- .Debug()
- .ApkFile(“../../../com.Abc.XYZ”)//APK will be part of the solution.
- .DeviceSerial(“ce081718341fbf1f05")
- .StartApp();
Getting the Serial Number of Device,
- adb devices
- List of devices attached
- ce081718341fbf1f05 device
- emulator-5554 device
iOS Setup
- //Already Installed on device
- return ConfigureApp
- .iOS
- .Debug()
- .InstalledApp("com.Abc.XYZ")// Bundle id
- .StartApp();
- //Specified Location
- return ConfigureApp
- .iOS
- .Debug()
- .AppBundle("../../../iOSAppProject/bin/iPhoneSimulator/Debug/iosapp.app")// Getting it from specific Location
- .StartApp();
Addition Setup Required for iOS
In your Ios Application, install Xamarin.TestClound.Agent .
In the finished launching function of iOS put the below code if you want to be enabled always .
- Xamarin.Calabash.Start();
Even you can put condition on enabling it .
#if ENABLE_TEST_CLOUD
Xamarin.Calabash.Start();
#endif
Make sure test cloud is enabled for iOS apps .
Steps to enable,
Right click on solution file-->options -->Complier--> define symbols
Add - ENABLE_TEST_CLOUD;

Now our Android and iOS setup are finished. Let's try to understand how we will automate that .
We are taking a scenario of Login Validation.
- IApp App;
- Query _Username = x => x.Marked("username"); //username is accessibility id for Username textfield
- Query _Password = x => x.Marked("username");
- App.Tap(_Username);
- App.EnterText("Valid Username");//So here we are tapping on username and entering the Correct username
- App.Tap(_Password);
- App.EnterText("Valid Password");//So here we are tapping on Password and entering the Password.
- App.Tap("Login");//This will search for button with text Login and serach for it .
Now we have successfully executed the login request.
To crosscheck whether we have successfully logged in or not we need to wait until it navigates to the next page.
So let's see how we can achieve that.
- App.WaitForElement(l => l.Marked("Login Success"), timeout: TimeSpan.FromSeconds(100)); //It will wait till the request tin eout after 100 Sec and if the next page title message is "Login success" It gets that element our test Case is pass.
- Assert.Pass(" we have succefully Logged In ");
So with this article we have suceesfully done the setup for UI Automation and we have gone through a scenario on how to execute it by taking the login example.
I am still working on some complex scenarios and will publish that soon!!!!
Happy Coding :)

Pinaki MishraPosted Jun 28, 2021, 5:59 AM
Thanks Pranav, nicely articulated. However, I am unable to launch any installed app from physical device using Xamarin.UItest. Let me walk through the steps what I performed: 1. Created Xamarin UI test (cross Platform), 2. connected my physical device to system with debug mode enabled. I can run the adb device command and get my device listed. 3. Tried to open an app which is already installed for example calculator app in device, like ConfigureApp .Android.InstalledApp("com.ABC.xyz") .DeviceSerial("E1BAN000321") .StartApp(); when I run the test, it gives below exception: System.Exception : Failed to execute: C:\Users\pinaki\AppData\Local\Android\Sdk\platform-tools\adb.exe -s E1BAN000321 shell am instrument -w com.ABC.xyz.test/sh.calaba.instrumentationbackend.ClearAppData3 - exit code: 1 java.lang.SecurityException: Permission Denial: starting instrumentation ComponentInfo{com.ABC.xyz.test/sh.calaba.instrumentationbackend.ClearAppData3} from pid=32696, uid=32696 not allowed because package com.ABC.xyz.test does not have a signature matching the target com.ABC.xyz.test at android.os.Parcel.readException(Parcel.java:2013) at android.os.Parcel.readException(Parcel.java:1959) at android.app.IActivityManager$Stub$Proxy.startInstrumentation(IActivityManager.java:5062) at com.android.commands.am.Instrument.run(Instrument.java:419) at com.android.commands.am.Am.runInstrument(Am.java:187) at com.android.commands.am.Am.onRun(Am.java:80) at com.android.internal.os.BaseCommand.run(BaseCommand.java:54) at com.android.commands.am.Am.main(Am.java:50) at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:285) INSTRUMENTATION_STATUS: Error=Permission Denial: starting instrumentation ComponentInfo{com.ABC.xyz.test/sh.calaba.instrumentationbackend.ClearAppData3} from pid=32696, uid=32696 not allowed because package com.ABC.xyz.test does not have a signature matching the target com.ABC.xyz INSTRUMENTATION_STATUS: id=ActivityManagerService INSTRUMENTATION_STATUS_CODE: -1
Vinod BadawadagiPosted Jan 28, 2020, 11:20 AM
Thank you Pranav, well explained.